//! 客户端测试

use crate::client::{BinanceClient, BinanceClientBuilder};
use crate::config::BinanceConfig;
use crate::{Environment, ProductType};

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_client_creation() {
        let config = BinanceConfig::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::Spot,
        );

        let client = BinanceClient::new(config);
        assert!(client.is_ok());
    }

    #[tokio::test]
    async fn test_client_builder() {
        let client = BinanceClientBuilder::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::UsdM,
        )
        .environment(Environment::Demo)
        .timeout(60)
        .retry_count(5)
        .build();

        assert!(client.is_ok());
    }

    #[tokio::test]
    async fn test_client_with_proxy() {
        let client = BinanceClientBuilder::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::Spot,
        )
        .proxy(
            Some("http://127.0.0.1:8080".to_string()),
            Some("socks5://127.0.0.1:1080".to_string()),
        )
        .build();

        assert!(client.is_ok());
    }

    #[tokio::test]
    async fn test_client_config_access() {
        let client = BinanceClientBuilder::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::Spot,
        )
        .build()
        .unwrap();

        let config = client.config();
        assert_eq!(config.api_key, "test_api_key");
        assert_eq!(config.secret_key, "test_secret_key");
        assert_eq!(config.product_type, ProductType::Spot);
    }

    #[tokio::test]
    async fn test_client_rest_access() {
        let client = BinanceClientBuilder::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::Spot,
        )
        .build()
        .unwrap();

        let rest_client = client.rest();
        assert!(rest_client.config().api_key == "test_api_key");
    }

    #[tokio::test]
    async fn test_client_websocket_access() {
        let mut client = BinanceClientBuilder::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::Spot,
        )
        .build()
        .unwrap();

        let ws_client = client.websocket();
        assert!(ws_client.is_ok());
    }

    #[tokio::test]
    async fn test_client_update_config() {
        let mut client = BinanceClientBuilder::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::Spot,
        )
        .build()
        .unwrap();

        let new_config = BinanceConfig::new(
            "new_api_key".to_string(),
            "new_secret_key".to_string(),
            ProductType::UsdM,
        );

        let result = client.update_config(new_config);
        assert!(result.is_ok());

        assert_eq!(client.config().api_key, "new_api_key");
        assert_eq!(client.config().secret_key, "new_secret_key");
        assert_eq!(client.config().product_type, ProductType::UsdM);
    }

    #[test]
    fn test_client_builder_chain() {
        let client = BinanceClientBuilder::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::CoinM,
        )
        .environment(Environment::Live)
        .timeout(120)
        .retry_count(10)
        .proxy(
            Some("http://proxy.example.com:8080".to_string()),
            Some("socks5://proxy.example.com:1080".to_string()),
        )
        .build();

        assert!(client.is_ok());

        let client = client.unwrap();
        let config = client.config();
        assert_eq!(config.environment, Environment::Live);
        assert_eq!(config.timeout_seconds, 120);
        assert_eq!(config.retry_count, 10);
        assert_eq!(config.http_proxy, Some("http://proxy.example.com:8080".to_string()));
        assert_eq!(config.ws_proxy, Some("socks5://proxy.example.com:1080".to_string()));
    }

    #[test]
    fn test_client_error_handling() {
        // 测试无效配置
        let client = BinanceClientBuilder::new(
            "".to_string(), // 空API密钥
            "".to_string(), // 空密钥
            ProductType::Spot,
        )
        .build();

        // 这里应该成功，因为验证在API调用时进行
        assert!(client.is_ok());
    }
}
